home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -seriously_amiga- / shareware / programming / c / amivogl-mdev / drivers / sun.c < prev    next >
C/C++ Source or Header  |  1998-01-12  |  16KB  |  906 lines

  1.  
  2. /*
  3.  * Vogl/Vogle driver for Sun using sunview.
  4.  *
  5.  */
  6. /*
  7.  * define VOGLE for VOGLE library or leave blank for VOGL library
  8. #define VOGLE 1
  9.  */
  10. #undef VOGLE
  11.  
  12. #include <stdio.h>
  13.  
  14. #include <suntool/sunview.h>
  15. #include <suntool/canvas.h>
  16. #include <fcntl.h>
  17. #include <errno.h>
  18.  
  19. #ifdef SUN_3_5
  20. #define event_action    event_id
  21. #endif
  22.  
  23. #ifdef VOGLE
  24. #include "vogle.h"
  25. #else
  26. #include "vogl.h"
  27. #endif
  28.  
  29. #define    CMAPSIZE    256
  30. #define    STDFONTDIR    "/usr/lib/fonts/fixedwidthfonts/"
  31.  
  32. #define MIN(x,y)    ((x) < (y) ? (x) : (y))
  33.  
  34. #define OP_WHITE    (PIX_SRC | PIX_COLOR(7) | PIX_DONTCLIP)
  35. #define OP_BLACK    (PIX_SRC | PIX_COLOR(0) | PIX_DONTCLIP)
  36. #define COL_WHITE    7
  37. #define COL_BLACK    0
  38.  
  39. static Pixwin    *pw_tmp, *pw;
  40.  
  41. #ifdef BASE_COL_SET
  42. static Pixwin    *pw0;
  43. #endif
  44.  
  45. static Pixrect    *backb;
  46. static Pixfont    *font_id;
  47. static int    wfd, blanket_win;
  48. static int    oldflags;
  49. static int    pwfd, h, w;
  50. static int    colour;
  51. static Rect    wrect;
  52.  
  53. static char    use_sunview_canvas = 0;
  54.  
  55. #define    DASHED        1
  56. #define    FATLINES    2
  57. static unsigned char    lineflags = 0;
  58.  
  59. static Pr_brush    brush = {1};
  60. static Pr_texture    *t = (Pr_texture *)NULL;
  61. static Pr_texture    tex = {
  62.                 (short *)NULL,    
  63.                 0,
  64.                 {1, 1, 1, 0},
  65.                 0,
  66.             };
  67.  
  68. /*
  69.  * default colour map
  70.  */
  71.  
  72. static int    colnum = 8;
  73. static u_char   red[CMAPSIZE] = {
  74.             0, 255, 0, 255, 0, 255, 0, 255, 0,
  75.         },
  76.         green[CMAPSIZE] = {
  77.             0, 0, 255, 255, 0, 0, 255, 255, 0,
  78.         },
  79.         blue[CMAPSIZE] = {
  80.             0, 0, 0, 0, 255, 255, 255, 255, 0,
  81.         };
  82.  
  83. /*
  84.  * redisplay
  85.  *
  86.  *    redisplay the window.
  87.  */
  88. static void redisplay(void)
  89. {
  90.     pw_damaged(pw);
  91.  
  92.     pw_repairretained(pw);
  93.  
  94.     pw_donedamaged(pw);
  95. }
  96.  
  97. /*
  98.  * To be called from a resize procedure from withing sunview
  99.  */
  100. int vo_sunview_canvas_size(
  101.   int sw,
  102.   int sh)
  103. {
  104.     w = sw;
  105.         h = sh;
  106.  
  107.         vdevice.sizeX = vdevice.sizeY = MIN(h, w);
  108.         vdevice.sizeSx = w;
  109.         vdevice.sizeSy = h;
  110.  
  111.     if (pw->pw_prretained) {
  112.         mem_destroy(pw->pw_prretained);
  113.         backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  114.     }
  115. }
  116.  
  117. /*
  118.  * vo_sunview_canvas
  119.  *
  120.  *     Tells VOGLE/VOGL to use a supplied sunview pixwin
  121.  */
  122. int vo_sunview_canvas(
  123.   Canvas canvas,
  124.   int cw,
  125.   int ch)
  126. {
  127.     pw = canvas_pixwin(canvas);
  128.     use_sunview_canvas = 1;
  129.  
  130.     w = cw;
  131.     h = ch;
  132.  
  133.     vdevice.sizeX = vdevice.sizeY = MIN(h, w);
  134.     vdevice.sizeSx = w;
  135.     vdevice.sizeSy = h;
  136.  
  137.     vdevice.depth = pw->pw_pixrect->pr_depth;
  138.     if (!pw->pw_prretained)    /* Make us retained */
  139.         backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  140.  
  141.     /* 
  142.      *  Set up the color map.  
  143.      */
  144.  
  145.     if (vdevice.depth > 1) {
  146.         pw_setcmsname(pw, "vogle");
  147.         pw_putcolormap(pw, 0, colnum, red, green, blue);
  148.     }
  149.  
  150.     wfd = (int)window_get(canvas, WIN_FD);
  151.  
  152.     /*
  153.      * Set non-blocking input for window.
  154.     oldflags = fcntl(wfd, F_GETFL, 0);
  155.     if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
  156.         perror("F_SETFL");
  157.         exit(1);
  158.     }
  159.      */
  160.  
  161.  
  162.     pw_batch_on(pw);
  163.  
  164. #ifndef VOGLE
  165.     vdevice.devname = "sun";
  166. #endif
  167.  
  168.     return(1);
  169. }
  170.  
  171. /*
  172.  * SUN_init
  173.  *
  174.  *    initialises drawing canvas to occupy current window
  175.  */
  176. int SUN_init(void)
  177. {
  178.     int        i, prefx, prefy, prefxs, prefys, bw;
  179.     char        name[WIN_NAMESIZE];
  180.     Inputmask    imk, imp;
  181.     int        rootfd;
  182.  
  183.     if (use_sunview_canvas)
  184.         return(1);
  185.  
  186.     pw = (Pixwin *)NULL;
  187.  
  188. #ifdef BASE_COL_SET
  189.     pw0 = pw;
  190. #endif
  191.  
  192.     /*
  193.      * get the gfx win so we have some default sizes to use
  194.      */
  195.     we_getgfxwindow(name);
  196.     pwfd = open(name, 2);
  197.     win_getrect(pwfd, &wrect);
  198.     
  199.         /*
  200.          * Get the input masks of the base window...
  201.          */
  202.         win_get_pick_mask(pwfd, &imp);
  203.         win_get_kbd_mask(pwfd, &imk);
  204.  
  205.  
  206.     /*
  207.      * get a new window (either going to be a blanket window or
  208.      * a window in it's own right)
  209.      */
  210.     if ((wfd = win_getnewwindow()) == -1) {
  211.         fprintf(stderr, "No new windows!\n");
  212.         exit(1);
  213.     }
  214.  
  215.     getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
  216.  
  217.     if (prefx > -1) {
  218.         wrect.r_left = prefx;
  219.         wrect.r_top = prefy;
  220.     }
  221.  
  222.     if (prefxs > -1) {
  223.         wrect.r_width = prefxs;
  224.         wrect.r_height = prefys;
  225.     }
  226.  
  227.     w = wrect.r_width;
  228.     h = wrect.r_height;
  229.  
  230.     bw = 3;
  231.     if (prefx > -1 || prefxs > -1) {
  232.         /*
  233.          * Make room for a 3 pixel border
  234.          */
  235.         if (wrect.r_left <= 2)
  236.             wrect.r_left = 0;
  237.         else
  238.             wrect.r_left -= bw;
  239.  
  240.         if (wrect.r_top <= 2)
  241.             wrect.r_top = 0;
  242.         else
  243.             wrect.r_top -= bw;
  244.  
  245.         wrect.r_width += 2 * bw;
  246.         wrect.r_height += 2 * bw;
  247.  
  248.         win_setrect(wfd, &wrect);
  249.  
  250.         /*
  251.          * get the parent (probably full screen window)
  252.          * so we can size our window to any size we like
  253.          * on the screen.
  254.          */
  255.         we_getparentwindow(name);
  256.         rootfd = open(name, 2);
  257.  
  258.         win_setlink(wfd, WL_PARENT, win_fdtonumber(rootfd));
  259.         win_setlink(wfd, WL_COVERED, WIN_NULLLINK);
  260.         win_insert(wfd);
  261.  
  262.         wmgr_top(wfd, rootfd);
  263.  
  264.         pw = pw_open(wfd);
  265.  
  266. #ifdef BASE_COL_SET
  267.         /*
  268.          * Get the pixrect for the window that we started in
  269.          * so we can set it's colourmap as well
  270.          */
  271.         pw0 = pw_open(pwfd);
  272. #endif
  273.  
  274.         close(rootfd);
  275.         blanket_win = 0;
  276.     } else {
  277.         win_insertblanket(wfd, pwfd);
  278.         pw = pw_region(pw_open(wfd), 0, 0, w, h);
  279.         blanket_win = 1;
  280.     }
  281.  
  282.     /*
  283.      * Set non-blocking input for window.
  284.      */
  285.     oldflags = fcntl(wfd, F_GETFL, 0);
  286.     if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
  287.         perror("F_SETFL");
  288.         exit(1);
  289.     }
  290.  
  291.     /*
  292.      * Setup the input masks for window.
  293.      */
  294.  
  295.     win_set_kbd_mask(wfd, &imk);
  296.         win_set_pick_mask(wfd, &imp);
  297.  
  298.     vdevice.depth = pw->pw_pixrect->pr_depth;
  299.  
  300.     /* 
  301.      *  Set up the color map.  
  302.      */
  303.  
  304.     if (vdevice.depth > 1) {
  305.         pw_setcmsname(pw, "vogle");
  306.         pw_putcolormap(pw, 0, colnum, red, green, blue);
  307. #ifdef BASE_COL_SET
  308.         if (pw0 != (Pixwin *)NULL) {
  309.             pw_setcmsname(pw0, "vogle");
  310.             pw_putcolormap(pw0, 0, colnum, red, green, blue);
  311.         }
  312. #endif
  313.     }
  314.  
  315.     if (prefx > -1 || prefxs > -1) {
  316.         /*
  317.          * Draw the border...
  318.          */
  319.         int    x0, y0, x1, y1;
  320.  
  321.         x0 = y0 = 0;
  322.         x1 = wrect.r_width - 1;
  323.         y1 = 0;
  324.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  325.         pw_vector(pw, x0 + 2, y0 + 2, x1 - 2, y1 + 2, OP_WHITE, COL_WHITE);
  326.         pw_vector(pw, x0 + 1, y0 + 1, x1 - 1, y1 + 1, OP_BLACK, COL_BLACK);
  327.         x0 = x1;
  328.         y0 = y1;
  329.         x1 = x0;
  330.         y1 = wrect.r_height - 1;
  331.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  332.         pw_vector(pw, x0 - 2, y0 + 2, x1 - 2, y1 - 2, OP_WHITE, COL_WHITE);
  333.         pw_vector(pw, x0 - 1, y0 + 1, x1 - 1, y1 - 1, OP_BLACK, COL_BLACK);
  334.         x0 = x1;
  335.         y0 = y1;
  336.         x1 = 0;
  337.         y1 = wrect.r_height - 1;
  338.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  339.         pw_vector(pw, x0 - 2, y0 - 2, x1 + 2, y1 - 2, OP_WHITE, COL_WHITE);
  340.         pw_vector(pw, x0 - 1, y0 - 1, x1 + 1, y1 - 1, OP_BLACK, COL_BLACK);
  341.         x0 = x1;
  342.         y0 = y1;
  343.         x1 = 0;
  344.         y1 = 0;
  345.         pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
  346.         pw_vector(pw, x0 + 2, y0 - 2, x1 + 2, y1 + 2, OP_WHITE, COL_WHITE);
  347.         pw_vector(pw, x0 + 1, y0 - 1, x1 + 1, y1 + 1, OP_BLACK, COL_BLACK);
  348.         pw_tmp = pw;
  349.         pw = pw_region(pw_tmp, 3, 3, w, h);
  350.         pw_close(pw_tmp);
  351.     }
  352.  
  353.  
  354.     backb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
  355.  
  356.     signal(SIGWINCH, redisplay);
  357.  
  358.     /*
  359.      *  Let VOGLE/VOGL know about the window size.
  360.      */
  361.         vdevice.sizeX = vdevice.sizeY = MIN(w, h);
  362.     vdevice.sizeSx = w;
  363.     vdevice.sizeSy = h;
  364.  
  365.     /*
  366.      * Set up batching.....(for speed and "pseudo" double buffering)
  367.      */
  368.     pw_batch_on(pw);
  369.  
  370.     return(1);
  371. }
  372.  
  373. /*
  374.  * SUN_exit
  375.  *
  376.  *    cleans up before returning the window to normal.
  377.  */
  378. int SUN_exit(void)
  379. {
  380.     long    nbytes;
  381.     int    i;
  382.     Event    event;
  383.  
  384.     if (use_sunview_canvas)
  385.         return(1);
  386.  
  387.     /*
  388.      * Flush all events for this window.
  389.      *
  390.      * While doing non-blocking input input_readevent returns -1 and
  391.      * errno == EWOULDBLOCK when everything has been read, so if 
  392.      * errno != EWOULDBLOCK then something naughty happened...
  393.      */
  394.     while (input_readevent(wfd, &event) >= 0)
  395.         ;
  396.  
  397.     if (errno != EWOULDBLOCK) {
  398.         perror("SUN_exit(flushing), input_readevent");
  399.         exit();
  400.     }
  401.  
  402.     /*
  403.      * reset wfd to blocking input.
  404.      */
  405.     if (fcntl(wfd, F_SETFL, oldflags) < 0) {
  406.         perror("oldflags, F_SETFL");
  407.         exit(1);
  408.     }
  409.  
  410.     if (blanket_win)
  411.         win_removeblanket(wfd);
  412.     else 
  413.         win_remove(wfd);
  414.  
  415.     signal(SIGWINCH, SIG_DFL);
  416.  
  417.     return(1);
  418. }
  419.  
  420. /*
  421.  * SUN_draw
  422.  *
  423.  *    draws a line from the current graphics position to (x, y).
  424.  *
  425.  * Note: (0, 0) is defined as the top left of the window on a sun (easy
  426.  * to forget).
  427.  */
  428. int SUN_draw(
  429.   int x,
  430.   int y)
  431. {
  432.     if (!lineflags)    /* If thin and solid */
  433.         pw_vector(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, PIX_SRC | PIX_COLOR(colour), colour);
  434.     else    /* Fat and/or dashed */
  435.         pw_line(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, &brush, t, PIX_SRC | PIX_COLOR(colour));
  436.  
  437.     if (vdevice.sync)
  438.         pw_show(pw);
  439. }
  440.  
  441. /*
  442.  * SUN_getkey
  443.  *
  444.  *    grab a character from the keyboard.
  445.  */
  446. int SUN_getkey(void)
  447. {
  448.     Event    event;
  449.  
  450.     pw_show(pw);
  451.  
  452.     do {
  453.         while ((input_readevent(wfd, &event) < 0) && (errno == EWOULDBLOCK))
  454.         ;    /* Nothing to read - wait for something */
  455.         
  456.     } while (!event_is_ascii(&event));    /* Wait for a key press */
  457.  
  458.     return(event_action(&event));
  459. }
  460.  
  461. /*
  462.  * SUN_checkkey
  463.  *
  464.  *    Check if a keyboard key has been hit. If so return it.
  465.  */
  466. static Event *saved_event;
  467.  
  468. int SUN_checkkey(void)
  469. {
  470.     static Event    event;
  471.     
  472.     if(saved_event == &event)
  473.         saved_event = NULL;
  474.  
  475.     if (saved_event && event_is_ascii(saved_event)) {
  476.         Event *tmp = saved_event;
  477.  
  478.         saved_event = NULL;
  479.         return(event_action(tmp));
  480.     }
  481.  
  482.     saved_event = NULL;
  483.  
  484.     if (input_readevent(wfd, &event) < 0) {
  485.         if (errno == EWOULDBLOCK) {
  486.             return(0);
  487.         } else {
  488.             perror("SUN_checkkey, input_readevent");
  489.             exit(1);
  490.         }
  491.     } else if (event_is_ascii(&event))
  492.         return(event_action(&event));
  493.     else
  494.         saved_event = &event;
  495.  
  496.     return(0);
  497. }
  498.         
  499.  
  500. /*
  501.  * SUN_locator
  502.  *
  503.  *    return the window location of the cursor, plus which mouse button,
  504.  * if any, is been pressed.
  505.  */
  506. int SUN_locator(
  507.   int *wx,
  508.   int *wy)
  509. {
  510.     int    but;
  511.     static Event    event;
  512.     
  513.     if (vdevice.sync)
  514.         pw_show(pw);
  515.  
  516.     but = 0;
  517.  
  518.     *wx = win_get_vuid_value(wfd, LOC_X_ABSOLUTE);
  519.     *wy = (int)vdevice.sizeSy - win_get_vuid_value(wfd, LOC_Y_ABSOLUTE);
  520.  
  521.     /* This used to work under 4.0 but not longer ..... Maybe
  522.      * SUN don't want us to use sunview anymore?
  523.      */
  524.     if (win_get_vuid_value(wfd, BUT(1)))
  525.         but |= 1;
  526.  
  527.     if (win_get_vuid_value(wfd, BUT(2)))
  528.         but |= 2;
  529.  
  530.     if (win_get_vuid_value(wfd, BUT(3)))
  531.         but |= 3;
  532.  
  533.     
  534.     if (use_sunview_canvas)
  535.         return(but);
  536.  
  537.     if (saved_event == &event) /*Don't Re-use a previously rejected event*/
  538.         saved_event = NULL;
  539.  
  540.     if (saved_event && event_is_button(saved_event) && event_is_down(saved_event)) {
  541.         if (event_action(saved_event) == MS_LEFT)
  542.             but |= 1;
  543.         if (event_action(saved_event) == MS_MIDDLE)
  544.             but |= 2;
  545.         if (event_action(saved_event) == MS_RIGHT)
  546.             but |= 4;
  547.  
  548.         saved_event = NULL;
  549.         return(but);
  550.     }
  551.  
  552.  
  553.     if (input_readevent(wfd, &event) < 0) {
  554.         if (errno == EWOULDBLOCK) {
  555.             return(0);
  556.         } else {
  557.             perror("SUN_locator, input_readevent");
  558.             exit(1);
  559.         }
  560.     } else if (event_is_button(&event) && event_is_down(&event)) {
  561.             if (event_action(&event) == MS_LEFT)
  562.                 but |= 1;
  563.             if (event_action(&event) == MS_MIDDLE)
  564.                 but |= 2;
  565.             if (event_action(&event) == MS_RIGHT)
  566.                 but |= 4;
  567.     } else
  568.         saved_event = &event;
  569.  
  570.     return(but);
  571. }
  572.  
  573. #ifdef VOGLE
  574. /*
  575.  * SUN_clear
  576.  *
  577.  *    Clear the screen to current colour
  578.  */
  579. int SUN_clear(void)
  580. {
  581.     pw_writebackground(pw, 0, 0, w, h, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP);
  582.  
  583.     if (vdevice.sync)
  584.         pw_show(pw);
  585. }
  586.  
  587. #else
  588.  
  589. /*
  590.  * SUN_clear
  591.  *
  592.  *    Clear the viewport to current colour
  593.  */
  594. int SUN_clear(void)
  595. {
  596.         unsigned int    vw = vdevice.maxVx - vdevice.minVx;
  597.         unsigned int    vh = vdevice.maxVy - vdevice.minVy;
  598.  
  599.     pw_writebackground(pw, 
  600.         vdevice.minVx, vdevice.sizeSy - vdevice.maxVy, 
  601.         vw, vh,
  602.         PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP
  603.     );
  604.  
  605.     if (vdevice.sync)
  606.         pw_show(pw);
  607. }
  608.  
  609. #endif
  610.  
  611. /*
  612.  * SUN_color
  613.  *
  614.  *    set the current drawing color index.
  615.  */
  616. int SUN_color(int ind)
  617. {
  618.     colour = ind;
  619. }
  620.  
  621. /*
  622.  * SUN_mapcolor
  623.  *
  624.  *    change index i in the color map to the appropriate r, g, b, value.
  625.  */
  626. int SUN_mapcolor(
  627.   int i,
  628.   int r,
  629.   int g,
  630.   int b)
  631. {
  632.     int    j;
  633.  
  634.     if (i >= 255 || vdevice.depth == 1)
  635.         return(-1);
  636.  
  637.     if (i >= colnum)
  638.         colnum = i;
  639.  
  640.     red[i] = r;
  641.     green[i] = g;
  642.     blue[i] = b;
  643.  
  644.     red[255] = (u_char)~red[0];
  645.     green[255] = (u_char)~green[0];
  646.     blue[255] = (u_char)~blue[0];
  647.  
  648.     pw_putcolormap(pw, 0, colnum, red, green, blue);
  649. #ifdef BASE_COL_SET
  650.     pw_putcolormap(pw0, 0, colnum, red, green, blue);
  651. #endif
  652. }
  653.     
  654. /*
  655.  * SUN_font
  656.  *
  657.  *   Set up a hardware font. Return 1 on success 0 otherwise.
  658.  *
  659.  */
  660. int SUN_font(char *fontfile)
  661. {
  662.     char    name[BUFSIZ];
  663.  
  664.     if (font_id != (Pixfont *)NULL)
  665.         pf_close(font_id);
  666.  
  667.     if ((font_id = pf_open(fontfile)) == NULL)
  668.         if (*fontfile != '/') {
  669.             strcpy(name, STDFONTDIR);
  670.             strcat(name, fontfile);
  671.             if ((font_id = pf_open(name)) == NULL)
  672.                 return(0);
  673.         } else 
  674.             return(0);
  675.  
  676.     vdevice.hheight = font_id->pf_defaultsize.y;
  677.     vdevice.hwidth = font_id->pf_defaultsize.x;
  678.  
  679.     return(1);
  680. }
  681.  
  682. /* 
  683.  * SUN_char
  684.  *
  685.  *     outputs one char - is more complicated for other devices
  686.  */
  687. int SUN_char(char c)
  688. {
  689.     char    *s = " ";
  690.  
  691.     s[0] = c;
  692.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
  693.  
  694.     if (vdevice.sync)
  695.         pw_show(pw);
  696. }
  697.  
  698. /*
  699.  * SUN_string
  700.  *
  701.  *    Display a string at the current drawing position.
  702.  */
  703. int SUN_string(char s[])
  704. {
  705.     pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(colour), font_id, s);
  706.  
  707.     if (vdevice.sync)
  708.         pw_show(pw);
  709. }
  710.  
  711. /*
  712.  * SUN_fill
  713.  *
  714.  *    fill a polygon
  715.  */
  716. int SUN_fill(
  717.   int n,
  718.   int x[],
  719.   int y[])
  720. {
  721.     struct    pr_pos    vlist[128];
  722.     int    i, npnts;
  723.  
  724.     if (n > 128)
  725.         verror("vogle: more than 128 points in a polygon");
  726.  
  727.     npnts = n;
  728.  
  729.     for (i = 0; i < n; i++) {
  730.         vlist[i].x = x[i];
  731.         vlist[i].y = vdevice.sizeSy - y[i];
  732.     }
  733.  
  734.     pw_polygon_2(pw, 0, 0, 1, &npnts, vlist, PIX_SRC | PIX_COLOR(colour) | PIX_DONTCLIP, (Pixwin *)NULL, 0, 0);
  735.  
  736.     vdevice.cpVx = x[n-1];
  737.     vdevice.cpVy = y[n-1];
  738.  
  739. /*
  740.     if (vdevice.sync)
  741.         pw_show(pw);
  742. */
  743. }
  744.  
  745. /*
  746.  * SUN_backb
  747.  *
  748.  *    swap to memory only drawing (backbuffer) - a little slow but it
  749.  * works on everything. 
  750.  */
  751. int SUN_backb(void)
  752. {
  753.     /*
  754.      * Batching is already on....
  755.      */
  756.     return(0);
  757. }
  758.  
  759. /*
  760.  * SUN_swapb
  761.  *
  762.  *    swap the front and back buffers.
  763.  */
  764. int SUN_swapb(void)
  765. {
  766.     if (vdevice.inbackbuffer)
  767.         pw_show(pw);
  768.  
  769.     return(0);
  770. }
  771.  
  772. /*
  773.  * SUN_frontb
  774.  *
  775.  *    draw in the front buffer
  776.  */
  777. int SUN_frontb(void)
  778. {
  779.     /*
  780.      * Make it visible anyway....
  781.      */
  782.     pw_show(pw);
  783. }
  784.  
  785. /*
  786.  * SUN_sync
  787.  *
  788.  *    Syncronise the display with what we thing has been output
  789.  */
  790. int SUN_sync(void)
  791. {
  792.     pw_show(pw);
  793. }
  794.  
  795. /*
  796.  * SUN_setls
  797.  *
  798.  *    Set the line style....
  799.  */
  800. int SUN_setls(int lss)
  801. {
  802.     
  803.     unsigned ls = lss;
  804.     static short    dashes[17];
  805.  
  806.     int    i, n, a, b, offset;
  807.  
  808.     if (ls == 0xffff) {
  809.         lineflags &= ~DASHED;
  810.         t = (Pr_texture *)NULL;
  811.         return;
  812.     }
  813.  
  814.     lineflags |= DASHED;
  815.  
  816.     for (i = 0; i < 16; i++)
  817.         dashes[i] = 0;
  818.  
  819.     for (i = 0; i < 16; i++)    /* Over 16 bits */
  820.         if ((ls & (1 << i)))
  821.             break;
  822.  
  823.     offset = i;
  824.  
  825. #define    ON    1
  826. #define    OFF    0
  827.         
  828.     a = b = OFF;
  829.     if (ls & (1 << 0))
  830.         a = b = ON;
  831.  
  832.     n = 0;
  833.     for (i = 0; i < 16; i++) {    /* Over 16 bits */
  834.         if (ls & (1 << i))
  835.             a = ON;
  836.         else
  837.             a = OFF;
  838.  
  839.         if (a != b) {
  840.             b = a;
  841.             n++;
  842.         }
  843.         dashes[n]++;
  844.     }
  845.     n++;
  846.     dashes[n] = 0;
  847.  
  848.     tex.pattern = &dashes[0];
  849.     tex.offset = offset;
  850.     t = &tex;
  851. }
  852.  
  853. /*
  854.  * SUN_setlw
  855.  *
  856.  *    Set the line style....
  857.  */
  858. int SUN_setlw(int lw)
  859. {
  860.     if (lw > 1) {
  861.         lineflags |= FATLINES;
  862.         brush.width = lw;
  863.     } else
  864.         lineflags &= ~FATLINES;
  865. }
  866.  
  867. /*
  868.  * the device entry
  869.  */
  870. static DevEntry sundev = {
  871.     "sun",
  872.     "screen.b.16",
  873.     "screen.b.12",
  874.     SUN_backb,
  875.     SUN_char,
  876.     SUN_checkkey,
  877.     SUN_clear,
  878.     SUN_color,
  879.     SUN_draw,
  880.     SUN_exit,
  881.     SUN_fill,
  882.     SUN_font,
  883.     SUN_frontb,
  884.     SUN_getkey,
  885.     SUN_init,
  886.     SUN_locator,
  887.     SUN_mapcolor,
  888. #ifndef VOGLE
  889.     SUN_setls,
  890.     SUN_setlw,
  891. #endif
  892.     SUN_string,
  893.     SUN_swapb,
  894.     SUN_sync
  895. };
  896.  
  897. /*
  898.  * _SUN_devcpy
  899.  *
  900.  *    copy the sun device into vdevice.dev.
  901.  */
  902. int _SUN_devcpy(void)
  903. {
  904.     vdevice.dev = sundev;
  905. }
  906.